//
//  BSWebViewController.swift
//  SurfEasy
//
//  Created by 薛永伟 on 2019/9/12.
//  Copyright © 2019 XueYongWei. All rights reserved.
//

import UIKit
import WebKit

class BSWebViewController: UIViewController {

    lazy var webviewToolBar: UIToolbar = {
        let view = UIToolbar.init()
        
        let back = UIButton.init(type: .custom)
        back.setTitle("<", for: .normal)
        back.setTitleColor(UIColor.red, for: .normal)
        let backItem = UIBarButtonItem.init(customView: back)
        
        let forward = UIButton.init(type: .custom)
        forward.setTitle(">", for: .normal)
        forward.setTitleColor(UIColor.red, for: .normal)
        let forwardItem = UIBarButtonItem.init(customView: forward)
        
        let search = UIButton.init(type: .custom)
        search.setTitle("🔍", for: .normal)
        search.setTitleColor(UIColor.red, for: .normal)
        let searchItem = UIBarButtonItem.init(customView: search)
        
        let menu = UIButton.init(type: .custom)
        menu.setTitle("三", for: .normal)
        menu.setTitleColor(UIColor.red, for: .normal)
        let menuItem = UIBarButtonItem.init(customView: menu)
        
        view.setItems([backItem,
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       forwardItem,
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       UIBarButtonItem.init(barButtonSystemItem: .fixedSpace, target: nil, action: nil),
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       searchItem,
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       menuItem],
                      animated: true)
        return view
    }()
    
    lazy var windowsToolBar: UIToolbar = {
        let view = UIToolbar.init()
        let new = UIButton.init(type: .custom)
        new.setTitle("新建", for: .normal)
        new.setTitleColor(UIColor.red, for: .normal)
        let newItem = UIBarButtonItem.init(customView: new)
        
        let edit = UIButton.init(type: .custom)
        edit.setTitle("编辑", for: .normal)
        edit.setTitleColor(UIColor.red, for: .normal)
        let editItem = UIBarButtonItem.init(customView: edit)
        
        let clear = UIButton.init(type: .custom)
        clear.setTitle("清空", for: .normal)
        clear.setTitleColor(UIColor.red, for: .normal)
        let clearItem = UIBarButtonItem.init(customView: clear)
        
        
        view.setItems([newItem,
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       editItem,
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       UIBarButtonItem.init(barButtonSystemItem: .fixedSpace, target: nil, action: nil),
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       UIBarButtonItem.init(barButtonSystemItem: .fixedSpace, target: nil, action: nil),
                       UIBarButtonItem.init(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
                       clearItem],
                      animated: true)
        return view
    }()
    
    lazy var progressView: UIProgressView = {
        let view = UIProgressView.init(progressViewStyle: .bar)
        view.progressTintColor = UIColor.init(rgb: 0x999999)
        return view
    }()
    
    lazy var webview: WKWebView = {
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        config.allowsPictureInPictureMediaPlayback = false
        config.allowsAirPlayForMediaPlayback = false
        config.preferences.javaScriptCanOpenWindowsAutomatically = false
        
//        if let jsPath = Bundle.main.path(forResource: "JSBridge", ofType: "js"){
//            config.userContentController = WKUserContentController()
//            var source = try! NSString(contentsOfFile: jsPath, encoding: String.Encoding.utf8.rawValue) as String
//            let userScript = WKUserScript.init(source: source, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)
//            config.userContentController.addUserScript(userScript)
//            config.userContentController.add(self, name: "OOFJS")
//        }
        
        let webview = WKWebView.init(frame: CGRect.zero, configuration: config)
//        webview.scrollView.bounces = false
        webview.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.new, context: nil)
        webview.addObserver(self, forKeyPath: "title", options: NSKeyValueObservingOptions.new, context: nil)
        webview.uiDelegate = self
        webview.allowsBackForwardNavigationGestures = true
        return webview
    }()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(webviewToolBar)
        webviewToolBar.snp.makeConstraints { (make) in
            make.bottom.left.right.equalToSuperview()
            make.height.equalTo(44.scaleLength)
        }
        
        view.addSubview(webview)
        webview.snp.makeConstraints { (make) in
            make.left.right.equalToSuperview()
            make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(0)
            make.bottom.equalTo(webviewToolBar.snp.top).offset(0)
        }
        
        view.addSubview(progressView)
        progressView.snp.makeConstraints { (make) in
            make.top.equalTo(webview.snp.top).offset(0)
            make.left.right.equalToSuperview()
            make.height.equalTo(1.scaleLength)
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        
        let url = URL.init(string: "https://baidu.com")!
        let request = URLRequest.init(url: url)
        webview.load(request)
    }
}

//MARK: - --------------KVO--------------
extension BSWebViewController{
    
    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {
        
        if let obj = object as? WKWebView,obj == webview {
            if keyPath == "estimatedProgress" {//进度
                if let value = change?[NSKeyValueChangeKey.newKey] as? Float{
                    self.progressView.progress = value
                }
                self.progressView.isHidden = self.progressView.progress > 0.99
            }else if keyPath == "title"{
//                self.title = webView.title
            }
        }
        
    }
}

//MARK: - --------------WKNavigationDelegate--------------
extension BSWebViewController:WKNavigationDelegate {
    
    /// 是否允许请求
    func webView(_ webView: WKWebView,
                 decidePolicyFor navigationAction: WKNavigationAction,
                 decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        
        decisionHandler(.allow)
        
    }
    /// 是否允许响应
    func webView(_ webView: WKWebView,
                 decidePolicyFor navigationResponse: WKNavigationResponse,
                 decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        
        decisionHandler(.allow)
    }
    
    /// 授权
    func webView(_ webView: WKWebView,
                 didReceive challenge: URLAuthenticationChallenge,
                 completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        
        if let trust = challenge.protectionSpace.serverTrust {
            completionHandler(.useCredential, URLCredential(trust: trust))
        } else {
            completionHandler(.performDefaultHandling, nil)
        }
    }
    
    /// main frame的导航开始请求
    func webView(_ webView: WKWebView,
                 didStartProvisionalNavigation navigation: WKNavigation!) {
        
    }
    /// 当main frame接收到服务重定向时调用
    func webView(_ webView: WKWebView,
                 didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        
    }
    /// 当main frame开始加载数据失败时，会回调
    func webView(_ webView: WKWebView,
                 didFailProvisionalNavigation navigation: WKNavigation!,
                 withError error: Error) {
        
    }
    
    /// 当内容开始返回时调用
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        
        YRLog("didCommit navigation", type: .info)
    }
    /// 当main frame导航完成时，会回调
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        
        YRLog("didFinish navigation", type: .info)
    }
    /// 当main frame最后下载数据失败时，会回调
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        
    }
    /// 当web content处理完成时，会回调
    func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
        
        YRLog("webViewWebContentProcessDidTerminate", type: .info)
    }
    
}

//MARK: - --------------WKUIDelegate--------------
extension BSWebViewController:WKUIDelegate{
    
    /// 要打开新的网页
    func webView(_ webView: WKWebView,
                 createWebViewWith configuration: WKWebViewConfiguration,
                 for navigationAction: WKNavigationAction,
                 windowFeatures: WKWindowFeatures) -> WKWebView? {
        
        if let url = navigationAction.request.url{
            webView.load(URLRequest.init(url: url))
        }
        return nil
    }
    
    /// 要关闭当前的网页
    func webViewDidClose(_ webView: WKWebView) {
        
        let alv = UIAlertController.init(title: "要关闭网页？", message: nil, preferredStyle: .alert)
        let cancle = UIAlertAction.init(title: "取消", style: .cancel) { (action) in
        }
        let OK = UIAlertAction.init(title: "确定", style: .default) { (action) in
            self.navigationController?.popViewController(animated: true)
        }
        alv.addAction(cancle)
        alv.addAction(OK)
        self.present(alv, animated: true, completion: nil)
    }
    
    /// 网页提示
    func webView(_ webView: WKWebView,
                 runJavaScriptAlertPanelWithMessage message: String,
                 initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping () -> Void) {
        
        let alv = UIAlertController.init(title: message, message: nil, preferredStyle: .alert)
        let OK = UIAlertAction.init(title: "好的", style: .default) { (action) in
            completionHandler()
        }
        alv.addAction(OK)
        self.present(alv, animated: true, completion: nil)
    }
    
    /// 网页询问
    func webView(_ webView: WKWebView,
                 runJavaScriptConfirmPanelWithMessage message: String,
                 initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping (Bool) -> Void) {
        
        let alv = UIAlertController.init(title: message, message: nil, preferredStyle: .alert)
        let cancle = UIAlertAction.init(title: "取消", style: .cancel) { (action) in
            completionHandler(false)
        }
        let OK = UIAlertAction.init(title: "确定", style: .default) { (action) in
            completionHandler(true)
        }
        alv.addAction(cancle)
        alv.addAction(OK)
        self.present(alv, animated: true, completion: nil)
    }
    
    /// 网页输入
    func webView(_ webView: WKWebView,
                 runJavaScriptTextInputPanelWithPrompt prompt: String,
                 defaultText: String?,
                 initiatedByFrame frame: WKFrameInfo,
                 completionHandler: @escaping (String?) -> Void) {
        
        let alv = UIAlertController.init(title: prompt, message: nil, preferredStyle: .alert)
        alv.addTextField { (tf) in
            tf.placeholder = "请输入"
        }
        
        let cancle = UIAlertAction.init(title: "取消", style: .cancel) { (action) in
            let text = alv.textFields?.first?.text
            completionHandler(text)
        }
        let OK = UIAlertAction.init(title: "确定", style: .default) { (action) in
            completionHandler(defaultText)
        }
        alv.addAction(cancle)
        alv.addAction(OK)
        self.present(alv, animated: true, completion: nil)
    }
}

//MARK: - --------------WKScriptMessageHandler--------------

extension BSWebViewController: WKScriptMessageHandler{
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        
        if message.name == "OOFJS" {
            if let dic = message.body as? NSDictionary, dic["fun"] != nil,
                let fun = (dic["fun"] as AnyObject).description{
            }
            
        }
    }
}
